import cv2
from flask import Flask, render_template, Response
import logging
from tools.log import log
from plugin.web.rest_api.car_status import car_status_bp
from plugin.web.rest_api.camera_control import camera_action_control_bp as camera_bp
from plugin.web.rest_api.car_control import car_action_control_bp as car_bp
from plugin.web.rest_api.car_control import setVisualControlHandel
import numpy as np
from ai_library.components.config import cfg
import multiprocessing as mp
from car_base.car_drive import CarDrive
from tools.databus.bus import workFlow

# logging.getLogger("werkzeug").setLevel(logging.WARNING)
app = Flask(__name__)
app.register_blueprint(car_bp)
app.register_blueprint(camera_bp)
app.register_blueprint(car_status_bp)


class FlaskTask():
    def __init__(self):
        global app

    def onExit(self):
        pass

    def worker(self, host="127.0.0.1", port=8080, state_dict:dict=None,
            webViewCsiFrameQueue=None, webViewIpcFrameQueue=None,
            stopFlag=None, q_send=None):
        """
        flask可视化交互界面启动插件
        :param host: 本机的IP地址（同一个局域网均可访问）
        :param port: 端口号（可随意设置）
        :param state_dict: 全局状态dict(存储flask可视化交互界面的动作指令及程序整体运行状态)
        :param webViewCsiFrameQueue: mipi摄像头图像帧
        :param webViewIpcFrameQueue: 网络摄像头图像帧
        :param stopFlag: 无人车状态反馈标志位
        :param q_send: 无人车数据发送消息队列
        :return:
        """

        # 设置需要控制的接口
        setVisualControlHandel(state_dict, CarDrive(stopFlag, q_send, with_flag=False))

        @app.route('/', methods=['GET', 'POST'])
        def base_layout():
            return render_template('ControlCar.html')

        @app.route('/AutoCar', methods=['GET', 'POST'])
        def new_layout():
            return render_template("AutoCar.html")

        def cameraCsi():
            while True:
                if webViewCsiFrameQueue.empty():
                    continue
                else:
                    img = webViewCsiFrameQueue.get()
                img = np.array(img).reshape(cfg["cam_height"], cfg["cam_width"], 3)
                ret, buf = cv2.imencode(".jpeg", img)
                yield (
                        b"--frame\r\nContent-Type: image/jpeg\r\n\r\n" + buf.tobytes() + b"\r\n\r\n"
                )

        def cameraIpc():
            while True:
                if webViewIpcFrameQueue.empty():
                    continue
                else:
                    img = webViewIpcFrameQueue.get()
                    if img != False:
                        img = np.array(img).reshape(cfg["cam_height"], cfg["cam_width"], 3)
                ret, buf = cv2.imencode(".jpeg", img)
                yield (
                        b"--frame\r\nContent-Type: image/jpeg\r\n\r\n" + buf.tobytes() + b"\r\n\r\n"
                )

        @app.route("/videostreamIpc/", methods=["GET"])
        def videostreamIpc():
            return Response(
                cameraIpc(), mimetype="multipart/x-mixed-replace; boundary=frame"
            )

        @app.route("/videostreamCsi/", methods=["GET"])
        def videostreamCsi():
            return Response(
                cameraCsi(), mimetype="multipart/x-mixed-replace; boundary=frame"
            )

        app.run(host=host, port=port, threaded=True)
        log.info("flask已成功启动！！")


def flaskPluginRegist(host="127.0.0.1", port=8080, state_dict:dict=None,
            webViewCsiFrameQueue=None, webViewIpcFrameQueue=None,
            stopFlag:mp.Value=None, q_send:mp.Queue=None):

    flask_task_plugin = FlaskTask()

    workFlow.registBus(flask_task_plugin.__class__.__name__,
                       flask_task_plugin.worker,
                       (host, port, state_dict,
                        webViewCsiFrameQueue, webViewIpcFrameQueue,
                        stopFlag, q_send),
                       flask_task_plugin.onExit)


if __name__ == "__main__":
    flask_task = FlaskTask()
    flask_task.worker()

# 在谷歌浏览器中打开此链接
# p2 = sp.Popen("chromium-browser --kiosk --app='http://127.0.0.1:8080'", shell=True)